#include <stdlib.h>
#include <stdio.h>

#include "event.h"
#include "eventHandler.h"

///////////////////////////////////////////
//////// EventHandlerConsumer  ///////////
//////////////////////////////////////////

EventHandlerConsumer::EventHandlerConsumer(CORBA::ORB_ptr __orb, EventHandler* e) : EventConsumer(__orb)
{
	evh = e;
}

EventHandlerConsumer::~EventHandlerConsumer()
{
	disconnect_push_consumer();
	disconnect_from_push_supplier();
}

void EventHandlerConsumer::disconnect_push_consumer()
{
	
}

void EventHandlerConsumer::push(const GenericObject& data)
{
	for (int i=0; i<evh->num_objects; i++)
	{
		evh->objects[i]->listen(data);
	}
}

///////////////////////////////////////////
//////// EventHandlerSupplier   ///////////
//////////////////////////////////////////

EventHandlerSupplier::EventHandlerSupplier(CORBA::ORB_ptr __orb, EventHandler* e) : EventSupplier(__orb)
{
	evh = e;
}

EventHandlerSupplier::~EventHandlerSupplier()
{
	disconnect_push_supplier();
	disconnect_from_push_consumers();
}

void EventHandlerSupplier::disconnect_push_supplier()
{
	
}

///////////////////////////////////////////
////////      EventHandler     ///////////
//////////////////////////////////////////

EventHandler::EventHandler(CORBA::ORB_ptr __orb)
{
	channel_out = new EventHandlerSupplier(__orb, this);
	channel_input = new EventHandlerConsumer(__orb, this);
	
	objects = NULL;
	num_objects = 0;
}

EventHandler::~EventHandler()
{
	if (num_objects != 0)
	{
		free(objects);
	}
	
	try {
		delete channel_input;
	}catch(const CORBA::Exception&)
	{
		
	}
	
	try{
		delete channel_out;
	}catch(const CORBA::Exception&)
	{
		
	}
}
	
int EventHandler::get_pos_obj(ListeningObject* obj)
{
	for (int i=0; i<num_objects; i++)
	{
		if (objects[i] == obj)
		{
			return i;
		}
	}
	
	return -1;
}	

void EventHandler::push(Event* ev)
{
	GenericObject data;
	
	ev->to_any(data);
	
	channel_out->push(data);
}
	
void EventHandler::register_object(ListeningObject* obj)
{
	if (get_pos_obj(obj) == -1)
	{
		num_objects++;
		
		ListeningObject** objects_aux = 
			(ListeningObject**)malloc( num_objects*sizeof(ListeningObject*) );
			
		for (int i=0; i<(num_objects-1); i++)
		{
			objects_aux[i] = objects[i];
		}
		
		objects_aux[num_objects-1] = obj;
		
		if (objects != NULL) free(objects);
		
		objects = objects_aux;
	}
}
	
void EventHandler::unregister_object(ListeningObject* obj)
{
	if ( (num_objects-1) == 0)
	{
		num_objects = 0;
		free(objects);
		objects = NULL;
	}
	
	int pos = get_pos_obj(obj);
	if (pos != -1)
	{
		if (pos != (num_objects-1))
		{
			ListeningObject* aux = objects[num_objects-1];
			objects[num_objects-1] = objects[pos];
			objects[pos] = aux;
		}
		
		num_objects--;
		
		ListeningObject** objects_aux = 
			(ListeningObject**)malloc( num_objects*sizeof(ListeningObject*) );
			
		for (int i=0; i<num_objects; i++)
		{
			objects_aux[i] = objects[i];
		}
		
		free(objects);
		
		objects = objects_aux;
	}
}
